/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.DeclaracoesIniciais;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Funcao.RegraArgsDeclaracao;
import analiseSintatica.Regras.Regra;
import analiseSintatica.Regras.Tipos.RegraTipo;
import analiseSintatica.estruturadados.ErroSintatico;
import analiseSintatica.estruturadados.NoArvore;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import analiseSintatica.Regras.Blocos.RegraCorpoFuncao;

/**
 *
 * @author Dede do Bem
 * 
 * 
 * <prototipo> ::= <tipo> identificador "(" [<args_declaracao>] ")"
 */
public class RegraPrototipo extends Regra{



    protected static Regra instancia;
    protected String estrutura = "<tipo> identificador '(' [<args_declaracao>] ')'";


    /**
     * Construtor privado necessario ao singleton
     */
    private RegraPrototipo() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraPrototipo getInstance() {
        if (instancia == null) {
            instancia = new RegraPrototipo();
        }
        return (RegraPrototipo) instancia;
    }

    

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

        ErroSintaticoException erros = new ErroSintaticoException();
        
        NoArvore NaoTerminalPrototipo = new NoArvore("<prototipo>", false);
        
       
        try{
            NaoTerminalPrototipo.adicionaFilho(RegraTipo.getInstance().analisar(listaTokens)); //cria filho da sub arvore de prototipo
        }catch (ErroSintaticoException e) {
			while(e.size() != 0)
				erros.addErros(e.getErros());
	}

        try{
            NaoTerminalPrototipo.adicionaFilho(reconheceToken(listaTokens, "identificador",estrutura));

        }catch(ErroSintaticoException e){

        }

        try{
            NaoTerminalPrototipo.adicionaFilho(reconheceLexema(listaTokens, "delimitador", "(",estrutura));
        }
        catch(ErroSintaticoException e){
            
        }

        try{
            if(RegraArgsDeclaracao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getLexema())){
                NaoTerminalPrototipo.adicionaFilho(RegraArgsDeclaracao.getInstance().analisar(listaTokens));
            }

        }catch(ErroSintaticoException e){

        }

        try{
            NaoTerminalPrototipo.adicionaFilho(reconheceLexema(listaTokens, "delimitador", ")",estrutura));
        }
        catch(ErroSintaticoException e){

        }


         System.out.println("Terminei Regra Prototipo");
        
        return NaoTerminalPrototipo;
    }
    
   

    @Override
    protected void setPrimeiro() {
        this.primeiro.add("char");
        this.primeiro.add("int");
        this.primeiro.add("float");
        this.primeiro.add("boolean");
        this.primeiro.add("identificador");
        this.primeiro.add("void");
        //this.primeiro = RegraTipo.getInstance().getPrimeiro();
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add(";");
        this.seguinte.add("{");
        //this.seguinte = RegraCorpoFuncao.getInstance().getPrimeiro();
    }

}
